#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb, const std::string &name)
    : m_loop(nullptr)
    , m_exiting(false)
    , m_thread(std::bind(&EventLoopThread::threadFunc, this), name)
    , m_callback(cb)
{
}

EventLoopThread::~EventLoopThread()
{
    m_exiting = true;
    if (m_loop != nullptr) {
        m_loop->quit();
        m_thread.join();
    }
}

// 开启线程
EventLoop *EventLoopThread::startLoop()
{
    // 启动底层的新线程
    m_thread.start();

    EventLoop* loop = nullptr;
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        while (m_loop == nullptr) {
            m_cond.wait(lock);
        }
        loop = m_loop;
    }

    return loop;
}

// 在单独的新线程里面运行 创建并开启事件循环
void EventLoopThread::threadFunc()
{
    EventLoop loop; // 创建一个独立的eventloop，与上面的线程一一对应，即：one loop per thread
    if (m_callback) {
        m_callback(&loop);
    }

    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_loop = &loop;
        m_cond.notify_one();
    }

    // 开启事件循环
    loop.loop();    // 会调用Poller.poll

    // 运行到下面的代码就说明事件循环已近退出了(一般是不会退出事件循环的)
    std::unique_lock<std::mutex> lock(m_mutex);
    m_loop = nullptr;

}
